package com.linhdoha.ui 
{
	import flash.display.DisplayObject;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.MouseEvent;
	/**
	 * ...
	 * @author Linhdoha
	 */
	public class TileList extends Sprite
	{
		private var contentHolder:Sprite;
		private var viewport:Sprite;
		private var _numItemH:uint;
		private var _numItemV:uint;
		private var _itemWidth:Number= 50;
		private var _itemHeight:Number= 50;
		private var _width:Number;
		private var _height:Number;
		private var isRowMode:Boolean = true;
		private var CRNumber:uint = 1;
		private var _spacing:Number = 0;
		private var _itemClass:Class = BaseItem;
		private var _dataList:Array;
		private var _leftEnable:Boolean;
		private var _rightEnable:Boolean;
		private var _upEnable:Boolean;
		private var _downEnable:Boolean;
		
		
		public function TileList(itemClass:Class, width:Number = 100, height:Number = 100, spacing:Number = 0) 
		{
			_itemClass = itemClass;
			_width = width;
			_height = height;
			_spacing = spacing;
			
			contentHolder = new Sprite();
			addChild(contentHolder);
			viewport = new Sprite();
			addChild(viewport);
			contentHolder.mask = viewport;
			
			resize();
		}
		
		public function addItem(data:Object):void {
			_dataList.push(data);
			drawChild();
			
		}
		
		public function removeItemAt(idx:uint):void {
			
		}
		
		public function clearAll():void {
			while (contentHolder.numChildren > 0) {
				contentHolder.removeChildAt(contentHolder.numChildren-1);
			}
		}
		
		override public function get width():Number { return _width; }
		
		override public function set width(value:Number):void 
		{
			_width = value;
			resize();
		}
		override public function get height():Number { return _height; }
		
		override public function set height(value:Number):void 
		{
			_height = value;
			resize();
		}
		
		public function set spacing(number:Number):void {
			_spacing = number;
			rearrange();
		}
		
		public function get spacing():Number {
			return _spacing;
		}
		
		public function set dataList(value:Array):void 
		{
			_dataList = value;
			drawChild();
		}
		
		public function get dataList():Array {
			return _dataList;
		}
		
		public function setCol(number:uint):void {
			isRowMode = false;
			CRNumber = number;
		}
		
		public function setRow(number:uint):void {
			isRowMode = true;
			CRNumber = number;
		}
		
		public function moveForward(number:uint):void {
			
			if (isRowMode) {
				var contentHolderRight:Number = contentHolder.x + contentHolder.width;
				var viewportRight:Number = viewport.x + viewport.width;
				var stepH:Number = number * (_itemWidth + _spacing);
				if (contentHolderRight > viewportRight) {
					if (Math.abs(contentHolderRight- viewportRight)<stepH) {
						number = Math.ceil(Math.abs(contentHolderRight - viewportRight) / (_itemWidth + _spacing));
					}
					contentHolder.x -= (_itemWidth + _spacing) * number;
				}
			} else {
				var contentHolderBottom:Number = contentHolder.y + contentHolder.height;
				var viewportBottom:Number = viewport.y + viewport.height;
				var stepV:Number = number * (_itemHeight + _spacing);
				if (contentHolderBottom>viewportBottom) {
					if (Math.abs(contentHolderBottom-viewportBottom)<stepV) {
						number = Math.ceil(Math.abs(contentHolderBottom - viewportBottom)/(_itemHeight + _spacing));
					}
					contentHolder.y -= (_itemHeight + _spacing) * number;
				}
			}
			rescroll();
		}
		
		public function moveBackward(number:uint):void {
			if (isRowMode) {
				if ((contentHolder.x+(_itemWidth + _spacing) * number) >= viewport.x) {
					//number = Math.floor(Math.abs(contentHolder.x - viewport.x)/(_itemWidth+_spacing));
					contentHolder.x = viewport.x;
				} else {
					contentHolder.x += (_itemWidth + _spacing)*number;
				}
				
			} else {
				if ((contentHolder.y+(_itemHeight + _spacing)*number) >=viewport.y) {
					//number = Math.floor(Math.abs(contentHolder.y-viewport.y)/(_itemHeight+_spacing));
					contentHolder.y = viewport.y;
				} else {
					contentHolder.y += (_itemHeight + _spacing) * number;
				}
				
			}
			rescroll();
		}
		
		private function rearrange():void {
			for (var i:int = 0; i < contentHolder.numChildren; i++) {
				BaseItem(contentHolder.getChildAt(i)).width = _itemWidth;
				BaseItem(contentHolder.getChildAt(i)).height = _itemHeight;
				if (isRowMode) {
					BaseItem(contentHolder.getChildAt(i)).y = (i % CRNumber) * (_itemHeight + _spacing);
					BaseItem(contentHolder.getChildAt(i)).x = Math.floor(i / CRNumber) * (_itemWidth + _spacing);
				} else {
					BaseItem(contentHolder.getChildAt(i)).x = (i % CRNumber) * (_itemWidth + _spacing);
					BaseItem(contentHolder.getChildAt(i)).y = Math.floor(i / CRNumber) * (_itemHeight + _spacing);
				}
			}
			
		}
		
		private function resize():void {
			viewport.graphics.clear();
			viewport.graphics.beginFill(0XFF0000, 0.3);
			viewport.graphics.drawRect(0, 0, _width, _height);
			viewport.graphics.endFill();
		}
		
		private function drawChild():void {
			clearAll();
			for (var i:int = 0; i < _dataList.length; i++) {
				var itemTemp:BaseItem = new _itemClass;
				itemTemp.data = _dataList[i];
				itemTemp.addEventListener(MouseEvent.MOUSE_DOWN, onItemMouseDown);
				itemTemp.addEventListener(MouseEvent.MOUSE_UP, onItemMouseUp);
				itemTemp.addEventListener(MouseEvent.MOUSE_OVER, onItemMouseOver);
				itemTemp.addEventListener(MouseEvent.MOUSE_OUT, onItemMouseOut);
				contentHolder.addChild(itemTemp);
			}
			rearrange();
			rescroll();
		}
		
		private function onItemMouseOut(e:MouseEvent):void 
		{
			var dataTemp:Object = BaseItem(e.currentTarget).data;
			dispatchEvent(new TileListEvent(TileListEvent.ITEM_MOUSE_OUT, dataTemp, true, false));
		}
		
		private function onItemMouseOver(e:MouseEvent):void 
		{
			var dataTemp:Object = BaseItem(e.currentTarget).data;
			dispatchEvent(new TileListEvent(TileListEvent.ITEM_MOUSE_OVER, dataTemp, true, false));
		}
		
		private function onItemMouseUp(e:MouseEvent):void 
		{
			var dataTemp:Object = BaseItem(e.currentTarget).data;
			dispatchEvent(new TileListEvent(TileListEvent.ITEM_MOUSE_UP, dataTemp, true, false));
		}
		
		private function onItemMouseDown(e:MouseEvent):void 
		{
			var dataTemp:Object = BaseItem(e.currentTarget).data;
			dispatchEvent(new TileListEvent(TileListEvent.ITEM_MOUSE_DOWN, dataTemp, true, false));
		}
		private function rescroll():void {
			if (contentHolder.width < viewport.width) {
				contentHolder.x = viewport.x;
			} else {
				if ((contentHolder.x + contentHolder.width) < (viewport.x + viewport.width)) {
					contentHolder.x = viewport.x + viewport.width - contentHolder.width;
				}
				if (contentHolder.x > viewport.x) {
					contentHolder.x = viewport.x;
				}
			}
			
			_leftEnable = contentHolder.x < viewport.x;
			_rightEnable = (contentHolder.x + contentHolder.width) > (viewport.x + viewport.width);
			_upEnable = contentHolder.y < viewport.y;
			_downEnable = (contentHolder.y + contentHolder.height) > (viewport.y + viewport.height);
			
			dispatchEvent(new Event(TileListEvent.RESCROLL));
		}
		
		public function get leftEnable():Boolean { return _leftEnable; }
		
		public function get rightEnable():Boolean { return _rightEnable; }
		
		public function get upEnable():Boolean { return _upEnable; }
		
		public function get downEnable():Boolean { return _downEnable; }
	}

}